package com.qys.livesMall.shop.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qys.livesMall.common.constants.Constants;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.exception.enums.ExceptionEnum;
import com.qys.livesMall.common.message.MessageServer;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.finance.enums.AccountBusinessTypeEnum;
import com.qys.livesMall.finance.model.dto.FinancePayDTO;
import com.qys.livesMall.finance.service.FinanceBusinessService;
import com.qys.livesMall.framework.utils.SecurityUtils;
import com.qys.livesMall.shop.constants.OrderStatus;
import com.qys.livesMall.shop.constants.PayMethod;
import com.qys.livesMall.shop.modal.dto.ShopProductAnchorOrderInfoDto;
import com.qys.livesMall.shop.modal.entity.H2ShopBase;
import com.qys.livesMall.shop.modal.entity.ShopOrderSku;
import com.qys.livesMall.shop.mapper.ShopOrderSkuMapper;
import com.qys.livesMall.shop.modal.vo.OrderAnchorListVO;
import com.qys.livesMall.shop.modal.vo.OrderFansRepurchaseVO;
import com.qys.livesMall.shop.modal.vo.ShopOrderSkuVO;
import com.qys.livesMall.shop.service.H2ShopBaseService;
import com.qys.livesMall.shop.service.ShopOrderSkuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author gmx
 * @since 2023-06-19
 */
@Service
public class ShopOrderSkuServiceImpl extends ServiceImpl<ShopOrderSkuMapper, ShopOrderSku> implements ShopOrderSkuService {

    @Resource
    private ShopOrderSkuMapper shopOrderSkuMapper;

    @Autowired
    private H2ShopBaseService h2ShopBaseService;

    @Autowired
    private MessageServer messageServer;

    @Autowired
    private FinanceBusinessService financeBusinessService;

    @Override
    public Long querySku(Long shopId) {
        LambdaQueryWrapper<ShopOrderSku> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ShopOrderSku::getShopId,shopId);
        lambdaQueryWrapper.ne(ShopOrderSku::getOrderStatus,OrderStatus.RECEIVED);
        return super.count(lambdaQueryWrapper);
    }

    @Override
    public List<ShopOrderSku> getNoSettlementOrder(Long shopId, Date endTime) {
        LambdaQueryWrapper<ShopOrderSku> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ShopOrderSku::getShopId,shopId);
        lambdaQueryWrapper.eq(ShopOrderSku::getOrderStatus, OrderStatus.RECEIVED);
        lambdaQueryWrapper.eq(ShopOrderSku::getSettlementStatus,OrderStatus.SettlementStatus.NO);
        lambdaQueryWrapper.le(ShopOrderSku::getEndTime,endTime.getTime());
        return list(lambdaQueryWrapper);
    }

    @Override
    public Page<ShopOrderSkuVO> listProductAnchorOrder(ShopProductAnchorOrderInfoDto shopProductAnchorDto) {
        Page<ShopOrderSkuVO> page = new Page<>(shopProductAnchorDto.getPageNum(),shopProductAnchorDto.getPageSize());
        return baseMapper.listProductAnchorOrder(page,shopProductAnchorDto);
    }

    @Override
    public ShopOrderSkuVO getProductAnchorInfo(String skuId) {
        return baseMapper.getProductAnchorInfo(skuId);
    }

    @Override
    public List<OrderFansRepurchaseVO> getFansRepurchase() {
        return baseMapper.getFansRepurchase();
    }

    @Override
    public List<ShopOrderSku> getByOrderId(Long orderId) {
        LambdaQueryWrapper<ShopOrderSku> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ShopOrderSku::getOrderId,orderId);
        return list(lambdaQueryWrapper);
    }

    @Override
    public List<ShopOrderSku> getPriceByOrderId(Long orderId) {
        LambdaQueryWrapper<ShopOrderSku> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(ShopOrderSku::getShopId,ShopOrderSku::getPrice,ShopOrderSku::getNum,ShopOrderSku::getId,ShopOrderSku::getSkuId);
        lambdaQueryWrapper.eq(ShopOrderSku::getOrderId,orderId);
        return list(lambdaQueryWrapper);
    }

    @Override
    public List<ShopOrderSku> getStatusByOrderId(Long orderId) {
        LambdaQueryWrapper<ShopOrderSku> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(ShopOrderSku::getOrderStatus,ShopOrderSku::getReturnBeforeStatus);
        lambdaQueryWrapper.eq(ShopOrderSku::getOrderId,orderId);
        return list(lambdaQueryWrapper);
    }

    @Override
    public List<ShopOrderSku> getByNoPayCost(LocalDateTime date) {
        LambdaQueryWrapper<ShopOrderSku> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ShopOrderSku::getCostPay, Constants.YesNoInt.NO);
        lambdaQueryWrapper.eq(ShopOrderSku::getOrderStatus,OrderStatus.UNSHIPPED);
        lambdaQueryWrapper.le(ShopOrderSku::getCreateTime,date);
        return list(lambdaQueryWrapper);
    }

    @Override
    public Map getByOrderNo(String orderNo) {
      return shopOrderSkuMapper.getUserOrderInfo(orderNo);
    }

    @Override
    public List<ShopOrderSku> getByOrderIdAndShop(Long shopId, Long orderId) {
        LambdaQueryWrapper<ShopOrderSku> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ShopOrderSku::getOrderId,orderId);
        lambdaQueryWrapper.eq(ShopOrderSku::getShopId,shopId);
        return list(lambdaQueryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R payCost(List<Long> orderIds) {
        H2ShopBase shop=h2ShopBaseService.queryShopBaseByUserId(SecurityUtils.getUserId());
        long now = System.currentTimeMillis();
        if (CollectionUtils.isEmpty(orderIds)){
            return messageServer.failMsg(ExceptionEnum.PARAM_IS_ERROR);
        }
        for (Long orderId:orderIds) {
            List<ShopOrderSku> orderSkus = getByOrderIdAndShop(shop.getId(),orderId);
            if(CollectionUtils.isEmpty(orderSkus)){
                continue;
            }
            for(ShopOrderSku orderSku:orderSkus) {
                if (Objects.equals(orderSku.getCostPay(), Constants.YesNoInt.NO)) {
                    BigDecimal amount=orderSku.getCostPrice().multiply(new BigDecimal(orderSku.getNum()));
                    FinancePayDTO payDTO = new FinancePayDTO();
                    payDTO.setUserId(shop.getUserId());
                    payDTO.setShopId(shop.getId());
                    payDTO.setBusinessNo(orderSku.getSkuOrderId());
                    payDTO.setAmountIncurred(amount);
                    payDTO.setBusinessType(AccountBusinessTypeEnum.PURCHASE);
                    financeBusinessService.pay(payDTO);
                    if (!payDTO.getSuccess()){
                        throw new QysException(payDTO.getMessage());
                    }
                }
                orderSku.setCostPay(Constants.YesNoInt.YES);
                orderSku.setCostPayType(PayMethod.CostPayType.BALANCE);
            }
            updateBatchById(orderSkus);
        }
        return R.ok();
    }

    @Override
    public List<ShopOrderSku> getReceivedOutTimeOrder(long startTime, long endTime) {
        LambdaQueryWrapper<ShopOrderSku> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(ShopOrderSku::getId,ShopOrderSku::getOrderStatus,ShopOrderSku::getConsignTime,ShopOrderSku::getUserId);
        lambdaQueryWrapper.eq(ShopOrderSku::getOrderStatus,OrderStatus.SHIPPED);
        lambdaQueryWrapper.gt(ShopOrderSku::getConsignTime,startTime);
        lambdaQueryWrapper.le(ShopOrderSku::getConsignTime,endTime);
        return list(lambdaQueryWrapper);
    }

    @Override
    public List<OrderAnchorListVO> getOrderAnchorList(DateTime yesterday) {
        return shopOrderSkuMapper.getOrderAnchorList(yesterday);
    }

    @Override
    public Integer getOrderNum(Long shopId,LocalDateTime startTime, LocalDateTime endTime) {
        return shopOrderSkuMapper.getOrderNum(shopId,startTime,endTime);
    }
}
